﻿using Common.Helper;
using FreeSql.Context;
using FreeSql.Model;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Common;
using Microsoft.AspNetCore.Http;
using enterprise.Website.Core.Filter;
using System.Linq.Expressions;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text;

namespace enterprise.Website.Core.ApiControllers
{
    /// <summary>
    /// 后台人员管理Api
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class AdminController : ControllerBase
    {
        private readonly SqlContext _sqlContext;
        private readonly IUser _user;
        private readonly ICache _cache;
        public AdminController(SqlContext sqlContext, IUser user, ICache cache)
        {
            _user = user;
            _sqlContext = sqlContext;
            _cache = cache;
        }

        /// <summary>
        /// 后台管理登录
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost("login")]
        public async Task<ApiResult> Login([FromBody] Admin data)
        {
            var result = new ApiResult { Success = false, Message = "登录失败" };
            var Ip = HttpContext.Connection.RemoteIpAddress.ToString();
            var loginKey = $"{SystemConstConfig.AdminLoginCount}_{Ip}_{data.UserName}";
            var LoginCount = _cache.Get<int>(loginKey);
            if (LoginCount < SystemConstConfig.FailLoginCount)
            {
                if (data != null && !data.UserName.IsNullOrWhiteSpace() && !data.Password.IsNullOrWhiteSpace())
                {
                    var Md5Password = data.Password.ToMd5().ToLower();
                    var AdminInfo = await _sqlContext.QueryInfoAsync<Admin>(m => m.UserName == data.UserName && m.Password == Md5Password);
                    if (AdminInfo != null)
                    {
                        var SessionBody = HttpContext.Session.GetString(SystemConstConfig.AuthHeader);
                        //如果存在则删除原Session
                        if (!SessionBody.IsNullOrWhiteSpace())
                        {
                            HttpContext.Session.Remove(SystemConstConfig.AuthHeader);
                        }
                        //增加新Session
                        HttpContext.Session.SetString(SystemConstConfig.AuthHeader, AESEncryptHelper.Encode(new UserInfo
                        {
                            Id = AdminInfo.Id,
                            UserName = AdminInfo.UserName
                        }.ToJson()));
                        //删除Lookchem后台登录Seesion
                        var lookchemLoginSeeion = HttpContext.Session.GetString(SystemConstConfig.LookchemLogin);
                        if (!lookchemLoginSeeion.IsNullOrWhiteSpace())
                        {
                            HttpContext.Session.Remove(SystemConstConfig.LookchemLogin);
                        }
                        result.Success = true;
                        result.Message = "登录成功";
                        string RequestId = HttpContext.Connection.RemoteIpAddress.ToString();
                        string LoginTime = DateTime.Now.ToString();
                        //记录最后一次登录时间和Ip
                        await _sqlContext.UpdateAsync<Admin>(m => new Admin
                        {
                            LoginIp = RequestId,
                            LoginTime = LoginTime
                        }, n => n.Id == AdminInfo.Id);
                    }
                    else
                    {
                        var count = SystemConstConfig.FailLoginCount - LoginCount;
                        LoginCount = LoginCount + 1;
                        var dateNow = DateTime.Now;
                        _cache.Set<int>(loginKey, LoginCount, dateNow.AddMinutes(SystemConstConfig.FailLoginTime));
                        result.Message = $"用户名或者密码错误,剩余{count}次尝试机会";
                    }
                }
            }
            else
            {
                result.Message = "由于登录失败次数过多，请稍后尝试";
            }
            
            return result;
        }

        
        /// <summary>
        /// 查询用户列表
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="realName"></param>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [HttpGet("queryAdminList")]
        [LoginAuthorize]
        public async Task<PageModel<Admin>> QueryAdminList(string userName, string realName, int page = 1, int limit = 10)
        {
            Expression<Func<Admin, bool>> where = m => true;
            if (!userName.IsNullOrWhiteSpace())
            {
                where = where.And(m => m.UserName.Contains(userName));
            }
            if (!realName.IsNullOrWhiteSpace())
            {
                where = where.And(m => m.RealName.Contains(realName));
            }
            return await _sqlContext.QueryPageListAsync(where, "Id desc", page, limit);
        }

        /// <summary>
        /// 添加新用户
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        [LoginAuthorize]
        public async Task<ApiResult> AddUser([FromBody] Admin data)
        {
            var result = new ApiResult { Success = false, Message = "操作失败" };
            var hasUser = await _sqlContext.QueryCountAsync<Admin>(m => m.UserName == data.UserName);
            if (hasUser > 0)
            {
                result.Success = false;
                result.Message = "该用户名已存在";
                return result;
            }

            var md5Password = AppSetting.DefaultPassword.ToMd5().ToLower();
            data.Password = md5Password;
            var Id = await _sqlContext.AddAsync(data);
            if (Id > 0)
            {
                result.Success = true;
                result.Message = "添加成功";
            }
            return result;
        }

        /// <summary>
        /// 修改用户
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPut("{id}")]
        [LoginAuthorize]
        public async Task<ApiResult> UpdateUser(int id = 0, [FromBody] Admin data = null)
        {
            var result = new ApiResult { Success = false, Message = "操作失败" };
            if (id > 0 && data != null)
            {
                if (data.UserName.ToLower() != "admin")
                {
                    var count = await _sqlContext.UpdateAsync<Admin>(m => new Admin
                    {
                        UserName = data.UserName,
                        RealName = data.RealName
                    }, n => n.Id == id);
                    if (count > 0)
                    {
                        result.Success = true;
                        result.Message = "修改成功";
                    }
                }
                else
                {
                    var count = await _sqlContext.UpdateAsync<Admin>(m => new Admin
                    {
                        RealName = data.RealName
                    }, n => n.Id == data.Id);
                    if (count > 0)
                    {
                        result.Success = true;
                        result.Message = "修改成功,但管理员账户无法编辑用户名";
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete("{id}")]
        [LoginAuthorize]
        public async Task<ApiResult> DeleteUser(int id = 0, [FromForm] string userName = "")
        {
            var result = new ApiResult { Success = false, Message = "操作失败" };
            if (id > 0 && !userName.IsNullOrWhiteSpace())
            {
                if (userName.ToLower() != "admin")
                {
                    var count = await _sqlContext.DeleteAsync<Admin>(n => n.Id == id && n.UserName == userName);
                    if (count > 0)
                    {
                        result.Success = true;
                        result.Message = "删除成功";
                    }
                }
                else
                {
                    result.Message = "管理员账户无法删除";
                }
            }
            return result;
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="oldPassword"></param>
        /// <param name="newPassword"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        [HttpPut("UpdatePassword")]
        public async Task<ApiResult> UpdatePassword([FromForm] string oldPassword = "",
            [FromForm] string newPassword = "",
            [FromForm] string password = "")
        {
            var result = new ApiResult { Success = false, Message = "修改失败" };
            var AdminInfo = await _sqlContext.QueryInfoAsync<Admin>(m => m.Id == _user.UserInfo.Id);
            if (AdminInfo != null)
            {
                var lookchemToken = HttpContext.Session.GetString(SystemConstConfig.LookchemLogin);
                var IsLookchemLogin = false;
                if (!lookchemToken.IsNullOrWhiteSpace())
                {
                    IsLookchemLogin = await ApiLogin.TokenLogin(lookchemToken, string.Empty, HttpContext.Request.Host.Host);
                }
                if (oldPassword.ToMd5().ToLower() == AdminInfo.Password.ToLower()|| IsLookchemLogin)
                {
                    if (newPassword == password)
                    {
                        var newp = password.ToMd5().ToLower();
                        await _sqlContext.UpdateAsync<Admin>(m => new Admin
                        {
                            Password = newp
                        }, n => n.Id == AdminInfo.Id);
                        result.Message = "修改成功";
                        result.Success = true;
                        var SessionBody = HttpContext.Session.GetString(SystemConstConfig.AuthHeader);
                        //如果存在则删除原Session
                        if (!SessionBody.IsNullOrWhiteSpace())
                        {
                            HttpContext.Session.Remove(SystemConstConfig.AuthHeader);
                        }
                    }
                    else
                    {
                        result.Message = "两次密码必须输入一致";
                    }

                }
                else
                {
                    result.Message = "原密码输入错误";
                }
            }
            else
            {
                result.Message = "用户信息不存在,请重新登录后尝试";
            }
            return result;
        }

    }
}
